package com.effective.java.clone;

public class CloneSupported01 implements Cloneable {

	private Integer i;
	private Element[] elements;

	public CloneSupported01() {

		this.i = 1;
		this.elements = new Element[5];
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public CloneSupported01 clone() {

		try {
			return (CloneSupported01) super.clone();
		}
		catch (CloneNotSupportedException e) {
			throw new RuntimeException(e);
		}
	}

	public static void main(String[] args) {

		CloneSupported01 instance1 = new CloneSupported01();
		instance1.elements[0] = new Element(1);
		instance1.elements[1] = new Element(2);
		CloneSupported01 instance2 = instance1.clone();

		System.out.println(instance1);
		System.out.println(instance2);

		// only changes value for instance1
		instance1.i = 3;

		// changes value for both instance1 and instance2
		instance1.elements[0].setJ(3);

		System.out.println(instance1);
		System.out.println(instance2);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String toString() {

		StringBuilder builder = new StringBuilder(super.toString() + "\\" + i.toString());
		for (Element e : this.elements) {
			builder.append(" - " + e + " - ");
		}
		return builder.toString();
	}

	private static class Element {

		private Integer j;

		public Element(Integer j) {

			this.j = j;
		}

		public void setJ(Integer j) {
			this.j = j;
		}

		@Override
		public String toString() {

			return super.toString() + "\\" + j;
		}

	}
}
